﻿using ASmile.CodeFactory.DaBLL;
using ASmile.CodeFactory.DaBLL.Builder;
using ASmile.CodeFactory.DBModel;
using ASmile.Win;
using ASmile.Extend;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace ASmile.CodeFactory
{
    public partial class FrmCodeBuilder : FrmBase
    {
        public FrmCodeBuilder()
        {
            InitializeComponent();
        }

        CodeBuilderBLL BLLObj { get; } = new CodeBuilderBLL();

        ArgPageData SearchArg { get; } = new ArgPageData();

        TConfig CurrConfig { get; set; }

        IBuilder CurrBuilder { get; set; }

        List<M_Table> CurrTables { set; get; }

        List<M_View> CurrViews { set; get; }

        List<M_Proc> CurrProcs { set; get; }

        void RefreshConfig()
        {
            OnPageChanged(1, ucPageNav1.OnePageCount, out int total);
            ucPageNav1.InitiControl(total);
        }

        private void FrmCodeBuilder_Load(object sender, EventArgs e)
        {
            RefreshConfig();
        }

        private void OnPageChanged(int pageNo, int pageSize, out int total)
        {
            SearchArg.PageNo = pageNo;
            SearchArg.PageSize = pageSize;
            SearchArg.SearchVal = tsTxtSearchConfig.Text;
            var ret = BLLObj.GetConfigs(SearchArg);
            dgvConfig.DataSource = ret.data;
            total = ret.count;
        }

        private void tsBtnSearch_Click(object sender, EventArgs e)
        {
            RefreshConfig();
        }

        private void tsTxtSearchConfig_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                RefreshConfig();
            }
        }

        //重连数据库
        private void tsBtnReConnect_Click(object sender, EventArgs e)
        {
            CurrBuilder = BuilderFactory.Create(new TConfig 
            { 
                ConnString = txtConnStr.Text,
                DBType = txtDBType.Text,
                NameSpace = txtNameSpace.Text,
            });
            ShowMessage("重置数据库参数完成");
        }

        private void dgvConfig_SelectionChanged(object sender, DataGridViewCellEventArgs e)
        {
            var selModel = dgvConfig.GetSelectedClassData<TConfig>(e.RowIndex);
            if (CurrConfig != null && selModel != CurrConfig)
            {
                if (!ShowQuestion("要切换配置信息吗？", "切换配置确认")) return;
            }
            if (selModel == null) return;
            txtCaption.Text = selModel.Caption;
            txtConnStr.Text = selModel.ConnString;
            txtDBType.Text = selModel.DBType;
            txtNameSpace.Text = selModel.NameSpace;
            txtSavePath.Text = selModel.SavePath;
            CurrBuilder = BuilderFactory.Create(selModel);
            dgvTable.DataSource = null;
            dgvProc.DataSource = null;
            dgvView.DataSource = null;
            CurrTables = null;            
            CurrViews = null;            
            CurrProcs = null;
        }

        private void tsBtnRefeshDBObj_Click(object sender, EventArgs e)
        {
            if (CurrBuilder == null)
            {
                ShowMessage("未选中配置");
                return;
            }
            if (tabControl1.SelectedTab == tabPageTable)
            {
                CurrTables = CurrBuilder.GetTables();
                dgvTable.DataSource = CurrTables;                
            }
            else if (tabControl1.SelectedTab == tabPageView)
            {
                CurrViews = CurrBuilder.GetViews();
                dgvView.DataSource = CurrViews;
            }
            else if (tabControl1.SelectedTab == tabPageProc)
            {
                CurrProcs = CurrBuilder.GetProcs();
                dgvProc.DataSource = CurrProcs;
            }
            else
            {
                MessageBox.Show("错误的选项卡");
            }
        }

        private void tsBtnSearchDB_Click(object sender, EventArgs e)
        {
            if (CurrBuilder == null)
            {
                ShowMessage("未选中配置");
                return;
            }
            if (tabControl1.SelectedTab == tabPageTable)
            {
                if (CurrTables == null)
                {
                    ShowMessage("表对象为空，请先刷新");
                    return;
                }
                string serVal = tsTxtSearchDBObj.Text;
                if (serVal.IsEmpty())
                {
                    dgvTable.DataSource = CurrTables;
                    return;
                }
                var rList = CurrTables.FindAll(s => s.TableName.ContainsLike(serVal) || s.TableRemark.ContainsLike(serVal));
                dgvTable.DataSource = rList;                
            }
            else if (tabControl1.SelectedTab == tabPageView)
            {
                if (CurrViews == null)
                {
                    ShowMessage("视图对象为空，请先刷新");
                    return;
                }
                string serVal = tsTxtSearchDBObj.Text;
                if (serVal.IsEmpty())
                {
                    dgvView.DataSource = CurrViews;
                    return;
                }
                var rList = CurrViews.FindAll(s => s.TableName.ContainsLike(serVal) || s.TableRemark.ContainsLike(serVal));
                dgvView.DataSource = rList;
            }
            else if (tabControl1.SelectedTab == tabPageProc)
            {
                if (CurrProcs == null)
                {
                    ShowMessage("视图对象为空，请先刷新");
                    return;
                }
                string serVal = tsTxtSearchDBObj.Text;
                if (serVal.IsEmpty())
                {
                    dgvProc.DataSource = CurrProcs;
                    return;
                }
                var rList = CurrProcs.FindAll(s => s.ProcName.ContainsLike(serVal) || s.ProcCaption.ContainsLike(serVal));
                dgvProc.DataSource = rList;
            }
            else
            {
                MessageBox.Show("错误的选项卡");
            }
        }

        private void tsTxtSearchDBObj_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                tsBtnSearchDB_Click(sender, e);
            }
        }

        /// <summary>
        /// 保存单个类文件
        /// </summary>
        void SaveCodeFileDialog(string dbObjName, string fileContent)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "*.cs|*.cs";
            sfd.FileName = dbObjName + ".cs";
            sfd.InitialDirectory = txtSavePath.Text;
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                SaveCodeToFile(fileContent, sfd.FileName);
                ShowMessage($"保存 {txtDBObjName.Text} 完成");
            }
        }
        /// <summary>
        /// 保存代码到文件
        /// </summary>
        /// <param name="codeStr">代码字符串</param>
        void SaveCodeToFile(string codeStr, string fileName)
        {
            if (string.IsNullOrEmpty(codeStr))
            {
                MessageBox.Show("代码为空!", "保存提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.Write(codeStr);
                }
            }
        }

        private void tsBtnSaveCode_Click(object sender, EventArgs e)
        {
            SaveCodeFileDialog(txtDBObjName.Text, txtCode.Text);
            
        }

        private void tsBtnGenerateCode_Click(object sender, EventArgs e)
        {
            if (CurrBuilder == null)
            {
                ShowMessage("未创建Builder, 请选择配置");
                return;
            }
            CreateCode();
        }

        void CreateCode()
        {
            if (tabControl1.SelectedTab == tabPageTable)
            {
                var selModel = dgvTable.GetSelectedClassData<M_Table>();
                txtCode.Text = CurrBuilder.GetTableCode(selModel);

                ShowMessage($"生成表代码 {selModel.TableName} 完成");
            }
            else if (tabControl1.SelectedTab == tabPageView)
            {
                var selModel = dgvView.GetSelectedClassData<M_View>();
                txtCode.Text = CurrBuilder.GetViewCode(selModel);
                ShowMessage($"生成视图代码 {selModel.TableName} 完成");
            }
            else if (tabControl1.SelectedTab == tabPageProc)
            {
                var selModel = dgvProc.GetSelectedClassData<M_Proc>();
                txtCode.Text = CurrBuilder.GetProcCode(selModel);
                ShowMessage($"生成存储过程代码 {selModel.ProcName} 完成");
            }
            else
            {
                MessageBox.Show("错误的选项卡");
            }
            txtCode.ScrollToCaret();
        }

        private void dgvDbObj_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            CreateCode();
        }

        //private void dgvTable_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        //{
        //    var selModel = dgvTable.GetSelectedClassData<M_Table>(e.RowIndex);
        //    txtCode.Text = CurrBuilder.GetTableCode(selModel);
        //}

        //private void dgvView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        //{
        //    var selModel = dgvView.GetSelectedClassData<M_View>(e.RowIndex);
        //    txtCode.Text = CurrBuilder.GetViewCode(selModel);
        //}

        //private void dgvProc_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        //{
        //    var selModel = dgvProc.GetSelectedClassData<M_Proc>(e.RowIndex);
        //    txtCode.Text = CurrBuilder.GetProcCode(selModel);
        //}

        private void dgvTable_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            coBoxDBObjType.SelectedIndex = 0;
            var selModel = dgvTable.GetSelectedClassData<M_Table>(e.RowIndex);
            txtDBObjName.Text = selModel.TableName;
        }

        private void dgvView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            coBoxDBObjType.SelectedIndex = 1;
            var selModel = dgvView.GetSelectedClassData<M_View>(e.RowIndex);
            txtDBObjName.Text = selModel.TableName;
        }

        private void dgvProc_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            coBoxDBObjType.SelectedIndex = 2;
            var selModel = dgvProc.GetSelectedClassData<M_Proc>(e.RowIndex);
            txtDBObjName.Text = selModel.ProcName;
        }

        private void tsBtnSetClipBoard_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(txtCode.Text);
            ShowMessage("保存到剪切板完成");
        }

        private void tsBtnSchema_Click(object sender, EventArgs e)
        {
            if (CurrBuilder == null)
            {
                ShowMessage("未选中配置");
                return;
            }
            FrmSchemaTest frm = new FrmSchemaTest(CurrBuilder.DaBLL);
            frm.ShowDialog();
        }

        private void tsbtnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}